// version 1.2
liwe.module = function ( name, history_cbacks, label )
{
	function _module ( name, history_cbacks, label )
	{
		var self = this;

		if ( ! label ) label = name;

		this.module_name = name;
		this.label = label;
		this._hist_events = {};
		this._dest_div = "block_main";  // Default id for rendering

		this.cbacks = { "req-error" : null };	// Custom module callbacks

		this.history_cbacks = history_cbacks;

		this.has_dashboard = false;

		this.em = new liwe.event_manager ( this );

		this.event_dispatch = function ( dict, data )
		{
			console.debug ( this );
			console.debug ( this._hist_events );

			var page = dict.get ( "_page" );
			var evt = this._hist_events.get ( page );

			if ( liwe.history.cbacks [ 'before-module' ] ) 
				liwe.history.cbacks [ 'before-module' ] ( this.module_name, dict, data );

			if ( ! evt ) 
			{
				if ( this.history_cbacks && ( evt = this.history_cbacks [ page ] ) )
				{
					evt = this [ evt ];
				} else {
					console.warn ( "Module: %s - Event: %s not handled", this.module_name, page );
					return;
				}
			}

			evt ( dict, data );
		};

		this.set_history = function ( page_name, cback, dict )
		{
			if ( typeof ( cback ) == "string" ) cback = this [ cback ];

			this._hist_events [ page_name ] = cback;

			if ( ! dict ) dict = {};
			dict [ "_page" ] = page_name;
			liwe.history.add_module ( this.module_name, dict );
		};

		this.init = function ()
		{
			// This is just a STUB!
		};

		this.get_dashboard = function ( cback )
		{
			return "";
		};

		this.ajax = function ( dct, cback, err_cback, url, easy )
		{
			var _obj = this;

			if ( typeof easy == "undefined" ) 
				easy = true;
			else
				easy = false;

			if ( typeof url == "undefined" )  url = null;
			if ( typeof cback == "undefined" )  cback = function ( v ) { console.debug ( "Module: %s - Result: %o", _obj.module_name, v ); };

			if ( ! err_cback ) err_cback = this.cbacks [ 'req-error' ];

			liwe.AJAX.request ( url, dct, cback, easy, false, err_cback ); 
		};

		self.templates = null;
		self._templates_loading = false;

		this.load_templates = function ( cback )
		{
			if ( self.templates !== null ) 
			{
				self._templates_loading = false;
				cback && cback ();
				return;
			}

			// Prevent load_templates() to get called multiple times (concurrency)
			if ( self._templates_loading ) 
			{
				console.debug ( "Templates for: %s already loading ...", self.module_name );
				setTimeout ( function () { self.load_templates ( cback ); }, 200 );
				return;
			}

			// Templates loading just started
			self._templates_loading = true;

			if ( self.templates === null )
			{
				console.debug ( "LOADING TEMPLATES: %s", self.module_name );
				self.ajax ( { action: self.module_name + ".ajax.get_templates" }, 
					function ( v ) 
					{ 
						self.templates = v [ 'templates' ]; 
						if ( cback ) cback ();
					}, function ( v ) 
					{
						console.error ( "Error loading templates for: %s. Data: %o", self.module_name, v );
					}
				);
			} else
				if ( cback ) cback ();

			// Templates loading completed
			self._templates_loading = false;
		};

		this.get_admin_actions = function ()
		{
			return this._actions;
		};

		this.get_plugin_actions = function ()
		{
			return this._plugin_actions;
		};

		this.register = function ( acts, plugin_acts )
		{
			this._actions = acts;
			this._plugin_actions = plugin_acts;

			if ( typeof ( system ) != 'undefined' && typeof ( system.admin ) != 'undefined' )
			{
				system.admin.module_register ( this );
				return true;
			}

			console.error ( "ERROR: could not register %s - module system not found", this.module_name );

			return false;
		};

		this.set_dest_div = function ( name )
		{
			this._dest_div = name;
		};

		this.plugin = function ( dest_div, params )
		{
			console.info ( "No plugin for: %s - params: %o", this.module_name, params );
		};

	/*
		this.valid_events = function ( events_list ) { return this.em.valid_events ( events_list ); };
		this.addEventListener = function ( type, cback ) { return this.em.addEventListener ( type, cback ); };
		this.removeEventListener = function ( type, cback ) { return this.em.removeEventListener ( type, cback ); };
		this.dispatchEvent = function ( type, source_event, params ) { return this.em.dispatchEvent ( type, source_event, params ); };
	*/
	}

	var mod = new _module ( name, history_cbacks, label );

	if ( liwe.history ) liwe.history.set_listener ( function ( dict, data ) { mod.event_dispatch ( dict, data ); }, name );

	return mod;
};
